package app.server.project.main.service.service.recharge;

import app.server.project.core.constants.Def;
import app.server.project.core.http.CMSLstResp;
import app.server.project.main.service.bo.dbquery.RechargeOrderParam;
import app.server.project.main.service.bo.event.RechargeSuccessEvent;
import app.server.project.main.service.constants.GlobalCfgKey;
import app.server.project.main.service.db.dao.cfg.GlobalCfgDao;
import app.server.project.main.service.db.dao.cfg.RechargeCfgDao;
import app.server.project.main.service.db.dao.user.RechargeOrderDao;
import app.server.project.main.service.db.entity.cfg.RechargeCfgEntity;
import app.server.project.main.service.dto.cms.BuyEnergyCfgDto;
import app.server.project.main.service.dto.recharge.*;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class RechargeService {

    private final Def def;
    private GlobalCfgDao globalCfgDao;
    private RechargeCfgDao rechargeCfgDao;
    private RechargeOrderDao rechargeOrderDao;
    private ApplicationEventPublisher applicationEventPublisher;
    private RechargeCfgDao cfgDao;


    public RechargeDto getRecharge(int typeId, String lang) {
        String tonWalletAddress = this.globalCfgDao.getStr(GlobalCfgKey.TON_Wallet_Address);
        int tonSanBox = Def.FALSE;
        if (this.globalCfgDao.has(GlobalCfgKey.TON_SAN_BOX)) {
            tonSanBox = this.globalCfgDao.getOneByKey(GlobalCfgKey.TON_SAN_BOX).getInt();
        }
        if (!this.rechargeCfgDao.getListMap().containsKey(typeId)) {
            return RechargeDto.of(new ArrayList<>(), false, tonWalletAddress, tonSanBox);
        }
        var list = this.rechargeCfgDao.getListMap().get(typeId);
        var lst = list.stream().sorted(Comparator.comparingLong(RechargeCfgEntity::getConsumeNum))
                .map(BuyEnergyCfgDto::of)
                .collect(Collectors.toList());


        return RechargeDto.of(lst, globalCfgDao.getDebug(), tonWalletAddress, tonSanBox);
    }

    public RechargeResp getAll() {
        String tonWalletAddress = this.globalCfgDao.getStr(GlobalCfgKey.TON_Wallet_Address);
        int tonSanBox = Def.FALSE;
        if (this.globalCfgDao.has(GlobalCfgKey.TON_SAN_BOX)) {
            tonSanBox = this.globalCfgDao.getOneByKey(GlobalCfgKey.TON_SAN_BOX).getInt();
        }
        return RechargeResp.of(this.rechargeCfgDao.getList(), false, tonWalletAddress, tonSanBox);
    }


    public CMSLstResp<RechargeOrderDto> getAllOrder(QueryRechargeOrderReq req) {
        Page<RechargeOrderDto> page = Page.of(req.getPageIndex() + 1, req.getPageSize());
        var param = new RechargeOrderParam();
        BeanUtil.copyProperties(req, param);
        if (param.getEndTime() != null) {
            param.setEndTime(param.getEndTime().plusDays(1));
        }
        var db = this.rechargeOrderDao.getBaseMapper().getAllByParam(page, param);
        db.getRecords().forEach(RechargeOrderDto::flushStr);
        return CMSLstResp.of(db.getRecords(), db.getTotal());
    }

    public void humanRecharge(HumanReq dto) {
        var cfg = this.cfgDao.getDataById(dto.getRechargeCfgId());
        var order = this.rechargeOrderDao.getOneByOrderId(dto.getId());
        this.applicationEventPublisher.publishEvent(RechargeSuccessEvent.create(dto.getUserId(), cfg, order));
        this.rechargeOrderDao.humanRechargeOrder(dto.getId());
    }

}
